package com.fram.controller.sys;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.fram.bean.sys.ResponseMsg;
import com.fram.bean.sys.pay.PayResultMsg;
import com.fram.common.canstant.ErrCode;
import com.fram.common.canstant.PublicConstant;
import com.fram.common.enums.PayCodeEnum;
import com.fram.common.exception.ProAffairException;
import com.fram.common.exception.ProException;
import com.fram.common.exception.ProRunTimeException;
import com.fram.common.util.PublicMethod;
import com.fram.common.util.XStreamUtils;
import com.fram.common.util.alipay.AlipayUtils;
import com.fram.common.util.apiversion.ApiVersion;
import com.fram.common.util.date.DateUtils;
import com.fram.common.util.json.JSONTools;
import com.fram.common.util.wxpay.WXPayUtils;
import com.fram.common.util.wxpay.WechatPayResponse;
import com.fram.entity.SysPayment;
import com.fram.mapper.SysPaymentMapper;
import com.fram.service.SystemService;
import com.fram.service.api.v1.OrderService;

/**
 * @作者： 陳曉鬆 @时间： 2020年4月29日 - 下午3:00:13 @description：->
 */
@RestController
@RequestMapping("/sys/{version}/pay")
public class PayController {

	private static Logger LOG = LoggerFactory.getLogger(PayController.class);

	@Resource(name = "systemService")
	private SystemService systemService;
	@Resource(name = "orderService")
	private OrderService orderService;
	@Autowired
	private SysPaymentMapper paymentMapper;

	/** 支付列表获取 */
	@ApiVersion(1.0)
	@RequestMapping("list")
	public ResponseMsg list(String view) {
		ResponseMsg msg = ResponseMsg.returnBeanBuild();
		try {
			msg.setData(systemService.payList(view));
		} catch (ProException e) {
			LOG.error("-系统-支付列表获取出错->{},{},{}", msg.getSessionId(), e.getErrorCode(), e.getErrorMsg());
			msg.setReturnCode(e.getErrorCode()).setReturnMsg(e.getErrorMsg());
		} catch (Exception e) {
			LOG.error("-系统-支付列表获取异常->{},{}", msg.getSessionId(), PublicMethod.printErrorTrace(e));
			msg.setReturnCode(ErrCode.ERR.getReturnCode()).setReturnMsg(ErrCode.ERR.getReturnMsg());
		}
		return msg;
	}

	/** 微信支付回调接口，供微信调用 */
	@ApiVersion(1.0)
	@RequestMapping(value = "wx/notify", produces = { "application/xml;charset=UTF-8" })
	public Object wxNotify(@RequestBody(required = false) String param) {
		try {
			LOG.info("-支付-微信回调内容信息：" + param);
			if (param.contains("<req_info>")) {
				return "<xml><return_code>SUCCESS</return_code><return_msg>OK</return_msg></xml>";
			}
			WechatPayResponse wechatPayResponse = XStreamUtils.xmlToBean(WechatPayResponse.class, param);
			if (wechatPayResponse != null && param.contains("return_code") && "SUCCESS".equals(wechatPayResponse.getReturn_code())) {
				SysPayment payment = paymentMapper.selectByAppid(wechatPayResponse.getAppid());
				if (payment == null) {
					throw new ProRunTimeException(ErrCode.NO_DATA.getReturnCode(), "支付信息不存在");
				}
				if (!WXPayUtils.isSignatureValid(param, payment.getPayAppKey())) {
					return "<xml><return_code>FAIL</return_code><return_msg>FAIL</return_msg></xml>";
				}

				PayResultMsg payResultMsg = new PayResultMsg();
				payResultMsg.setBillNo(wechatPayResponse.getTransaction_id());
				payResultMsg.setOrderNumber(wechatPayResponse.getOut_trade_no());
				payResultMsg.setPayTime(DateUtils.DF_CLOSED.get().parse(wechatPayResponse.getTime_end()));
				payResultMsg.setPayPrice(wechatPayResponse.getTotal_fee().divide(new BigDecimal("100")).setScale(2, BigDecimal.ROUND_HALF_UP));
				payResultMsg.setPayType(PayCodeEnum.WECHAT.getType());
				payResultMsg.setPayTypeName(PayCodeEnum.WECHAT.getPayName());
				payResultMsg.setAppid(wechatPayResponse.getAppid());
				payResultMsg.setOpenid(wechatPayResponse.getOpenid());

				// 判断去哪里执行回调参数
				if (payResultMsg.getOrderNumber().indexOf(PublicConstant.ORDER_TYPE_2 + "T") == 0) {// 商品支付回调
					orderService.dealPayNotify(payResultMsg);
				}

				return "<xml><return_code>SUCCESS</return_code><return_msg>OK</return_msg></xml>";
			}
		} catch (ProAffairException e) {
			LOG.error("-支付-微信支付回调->{}->param:{}", e.getErrorMsg(), param);
			if (ErrCode.NO_DATA.getReturnCode().equals(e.getErrorCode())) {// 找不到订单数据，直接退款
				// 退款操作
				return "<xml><return_code>SUCCESS</return_code><return_msg>OK</return_msg></xml>";
			}
		} catch (Exception e) {
			LOG.error("-支付-微信支付回调异常->param:{}->异常：{}", param, PublicMethod.printErrorTrace(e));
		}
		return "<xml><return_code>FAIL</return_code><return_msg>FAIL</return_msg></xml>";
	}

	/** 支付宝支付回调接口，供支付宝调用 */
	@ApiVersion(0.1)
	@RequestMapping(value = "alipay/notify")
	public Object orderAliPayMsg(HttpServletRequest request) {
		Map<String, String> parameters = null;
		Enumeration<String> params = request.getParameterNames();
		if (params != null) {
			parameters = new HashMap<String, String>();
			while (params.hasMoreElements()) {
				String paramName = params.nextElement();
				String value = request.getParameter(paramName);
				parameters.put(paramName, value);
			}
		}
		LOG.info("-支付-支付宝回调内容信息：{}", JSONTools.obj2json(parameters));
		try {
			if (parameters == null) {
				throw new ProRunTimeException("支付宝 参数为null");
			}
			if (!"TRADE_SUCCESS".equals(parameters.get("trade_status"))) {
				throw new ProRunTimeException("支付-支付宝状态不对:" + parameters.get("trade_status"));
			}
			SysPayment payment = paymentMapper.selectByAppid(parameters.get("app_id"));
			if (payment == null) {
				throw new ProRunTimeException(ErrCode.NO_DATA.getReturnCode(), "支付信息不存在");
			}
			if (!AlipayUtils.isSign(payment, parameters)) {
				throw new ProRunTimeException(ErrCode.NO_DATA.getReturnCode(), "支付信息验证错误");
			}
			PayResultMsg payResultMsg = new PayResultMsg();
			payResultMsg.setBillNo(parameters.get("trade_no"));
			payResultMsg.setOrderNumber(parameters.get("out_trade_no"));
			try {
				payResultMsg.setPayTime(DateUtils.DF_SEPARATE.get().parse(parameters.get("gmt_payment")));
			} catch (ParseException e) {
				e.printStackTrace();
			}
			payResultMsg.setPayPrice(new BigDecimal(parameters.get("total_amount")));
			payResultMsg.setPayType(PayCodeEnum.ALIPAY.getType());
			payResultMsg.setPayTypeName(PayCodeEnum.ALIPAY.getPayName());

			// 判断去哪里执行回调参数
			if (payResultMsg.getOrderNumber().indexOf(PublicConstant.ORDER_TYPE_2 + "T") == 0) {// 商品支付回调
				orderService.dealPayNotify(payResultMsg);
			}
			return "true";
		} catch (ProAffairException e) {
			LOG.error("-支付-支付宝支付回调->{}->param:{}", e.getErrorMsg(), parameters);
			if (ErrCode.NO_DATA.getReturnCode().equals(e.getErrorCode())) {// 找不到订单数据，直接退款
				// 退款操作
				return "false";
			}
		} catch (Exception e) {
			LOG.error("-支付-支付宝支付回调异常->param:{}->异常：{}", parameters, PublicMethod.printErrorTrace(e));
		}
		return "false";
	}
}
